#include <Arduino.h>
#include "cJSON.h"

#include "esp_sntp.h"
#include "c3log.h"
#include "Trace.h"

const char *g_apcNtpServer[] = {
    "time2.cloud.tencent.com",
    "ntp1.aliyun.com",
    "cn.ntp.org.cn",
    "tw.ntp.org.cn",
    "hk.ntp.org.cn",
    "us.ntp.org.cn",
    "1.pool.ntp.org",
};

const int32_t gmtSec_China_Offset = 8 * 3600;

void time_sync_notification_cb(struct timeval* tv) {    // 通知时间同步事件
    LOGI("Notification of a time synchronization event");
    struct tm timeinfo = {0};
    // convert to China Time
    tv->tv_sec += gmtSec_China_Offset;
    time_t curTime = (time_t)tv->tv_sec;
    localtime_r(&curTime, &timeinfo);
    settimeofday(tv, NULL);
    LOGI("%d-%d-%d %d:%d:%d", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
             timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
    // sntp_stop();
}

// 初始化SNTP相关函数
static void initialize_sntp(void) {
    LOGI("Initializing SNTP, SNTP_MAX_SERVERS:%d", SNTP_MAX_SERVERS);
    /*1,2,3函数主要作用就是通过SNTP，同步时间*/
    sntp_setoperatingmode(SNTP_OPMODE_POLL);  // 1，设置SNTP操作模式
    sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED);

    uint8_t ucServNum = sizeof(g_apcNtpServer) / sizeof(g_apcNtpServer[0]);
    for (uint8_t cnt = 0; cnt < ucServNum; cnt++) {
        sntp_setservername(cnt, g_apcNtpServer[cnt]);
    }
    sntp_set_time_sync_notification_cb(
        time_sync_notification_cb);         // 设置时间同步通知事件
    sntp_init();  // 3，SNTP初始化
}

// 获取NTP服务器的时间, 后台获取
void obtain_timeThread(void *) {
    TRACE_B();
    // ESP_ERROR_CHECK(esp_netif_init());
    // ESP_ERROR_CHECK(esp_event_loop_create_default());
    initialize_sntp();
}

/*
{
    "status": 1,
    "data": {
        "timestamp": 1616556071,
        "microtime": 1616556071.259844,
        "gmt": "2021-03-24 03:21:11",
        "utc": "2021-03-24T03:21:11Z",
        "timezone": "Shanghai"
    },
    "req_id": "3b853233236df4a63608"
}
*/
HTTPClient http;
int obtainTimeFromhttp() {
    http.begin("api.uukit.com", 80, "/time");
    int httpCode = http.GET();
    if (httpCode == HTTP_CODE_OK) {
        cJSON *pJsonRoot = cJSON_Parse(http.getString().c_str());
        if (pJsonRoot != NULL) {
            cJSON *pTmpJson = cJSON_GetObjectItem(pJsonRoot, "data");
            pTmpJson = cJSON_GetObjectItem(pTmpJson, "timestamp");
            double time_sec = cJSON_GetNumberValue(pTmpJson);
            LOGI("time_sec:%.2lf", time_sec);
            // update time
            struct timeval tv = {0};
            tv.tv_sec = (uint32_t)time_sec + gmtSec_China_Offset;
            settimeofday(&tv, NULL);
        }
    }
    http.end();
    return 0;
}
